/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package taskmanager2ndedition.server;

import java.beans.XMLEncoder;
import java.io.ByteArrayOutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import taskmanager2ndedition.Cmd;
import java.lang.reflect.Method;
import java.util.List;
import taskmanager2ndedition.Connection;
import taskmanager2ndedition.exceptions.MethodNotFoundException;
import taskmanager2ndedition.exceptions.*;
import taskmanager2ndedition.ClientUser;

/**
 *
 * @author Александр
 * 
 *  Command interpreter
 * 
 */
public class CmdInterpretator {
    
    private ServerConnection connection;
    private static ServerController controller;
    
    public static void setController(ServerController controller){
        CmdInterpretator.controller = controller;                
    }
    
    public CmdInterpretator(ServerConnection connection){
        this.connection = connection;
    }    
    
    public ServerConnection getConnection(){
        return connection;
    }
    
    public void generateResponce(Cmd cmd){
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        XMLEncoder encoder = new XMLEncoder(outputStream);
        encoder.writeObject(cmd);
        encoder.flush();
        encoder.close();
        connection.send(outputStream.toString());
    }
   
    public Object performRequest(String cmdString){
        try {
            if (cmdString == null){
                return null;
            }
            
            Cmd query = Cmd.fromString(cmdString);
            List params = query.getParams();
            params.add(this);
            query.setParams(params);
            Method method = findMethod(query);
            return method.invoke(controller, query.getParams().toArray());
          
        } catch(MethodNotFoundException ex){
            controller.sendErrorMessage(ex, this);
        } catch (Exception ex) {
            Logger.getLogger(CmdInterpretator.class.getName()).log(Level.SEVERE, null, ex);
        } 
        
        return null;
    }
    
    private Method findMethod(Cmd cmd) throws MethodNotFoundException{
        try {
            Class [] params = new Class[cmd.getParams().size()];
            for (int i = 0; i < cmd.getParams().size(); i++){
                params[i] = cmd.getParams().get(i).getClass();
            }
            return ServerController.class.getMethod(cmd.getMethod(), params);
        } catch (Exception ex){
            throw new MethodNotFoundException();
        }
    }
    
}
